<template>
  <el-container class="rovalflow-container">
    <el-header class="header">
      <div class="header-left">
        <div class="nav-back" @click="toReturn">
          <el-icon class="m-icon"><i-ep-arrow-left /></el-icon>
        </div>
        <div class="nav-title">{{ workFlowDef.flowName }}</div>
      </div>
      <div class="header-center">
        <div class="nav-container">
          <div class="ghost-bar" :style="'transform: translateX('+activeStep*150+'px);'" />
          <div class="nav-item" :class="{active: activeStep===0}" @click="activeStep=0"><span class="order-num">1</span>基础设置</div>
          <div class="nav-item" :class="{active: activeStep===1}" @click="activeStep=1"><span class="order-num">2</span>表单设计</div>
          <div class="nav-item" :class="{active: activeStep===2}" @click="activeStep=2"><span class="order-num">3</span>流程设计</div>
          <div class="nav-item" :class="{active: activeStep===3}" @click="activeStep=3"><span class="order-num">4</span>高级设置</div>
        </div>
      </div>
      <div class="header-right">
        <el-button round @click="saveSet">发布</el-button>
      </div>
    </el-header>
    <el-main class="main">
      <section v-show="activeStep===0" class="setting-container">
        <basic-setting ref="basicRef" v-model="workFlowDef" :flow-group-options="flowGroupOptions" />
      </section>

      <section v-if="activeStep===1" class="content-container">
        <ep-form-making
          v-model="formMaking"
          :options="formMakingOptions"
          :hide-fields="hideFields"
          :show="activeStep===1"
          :used-condition-ids="usedConditionIds"
          :form-templates="formTemplates"
        />
      </section>

      <section v-show="activeStep===2" class="content-container">
        <app-workflow
          ref="workflowRef"
          v-model="usedConditionIds"
          :widget-list="formMaking.widgetList"
          :user-list="userList"
          :role-list="roleList"
          :process-config="processConfig"
          :approver-types="[1,4]"
          :on-change="onChange"
        />
      </section>

      <section v-show="activeStep===3" class="setting-container">
        <advanced-setting v-model="advanced" />
      </section>
    </el-main>
  </el-container>
</template>

<script>
import _ from 'lodash'
import { ref, reactive, toRefs, onMounted } from 'vue'
import { useNotification, useLoading } from '@/composables'

export default {
  name: 'AppRovalflow',
  setup() {
    const notification = useNotification()
    const loading = useLoading()

    const state = reactive({
      workFlowDef: { // 基础设置表单
        flowName: '',
        flowImg: '',
        flowGroup: '',
        flowRemark: ''
      },
      formMaking: { // 表单设计器
        widgetList: [], // 表单数据
        formConfig: {}
      },
      flowGroupOptions: [], // 分组类型
      userList: [], // 用户列表
      roleList: [], // 角色列表
      advanced: {}, // 高级设置
      formTemplates: [] // 模板数据
    })

    const activeStep = ref(0)

    const dialogVisible = ref(false)

    const basicRef = ref(null)
    const workflowRef = ref(null)

    /** 表单设计器属性 */
    const formMakingOptions = {
      customShow: true, // 显示表单模板
      nameReadonly: false, // 禁止修改组件名称
      clearButtonShow: true, // 显示清空按钮
      previewButtonShow: true, // 显示预览按钮
      exportJsonButtonShow: false // 显示导出JSON按钮
    }

    /** 表单设计器隐藏字段 */
    const hideFields = [
      'fileupload',
      'imgupload',
      'cascader',
      'number',
      'radio',
      'checkbox',
      'time',
      'text'
    ]

    /** 流程设计器数据 */
    const processConfig = reactive({
      tableId: undefined,
      flowPermission: [],
      nodeConfig: {}
    })

    /** 已作为条件项组件ids */
    const usedConditionIds = ref([])

    onMounted(() => {
      loading.open()

      // 后台获取数据
      setTimeout(async() => {
        state.flowGroupOptions = [{
          'label': '出勤',
          'value': '1'
        }]

        state.userList = [
          {
            id: 'dept01',
            type: 2,
            name: '研发部门',
            children: [{
              id: 'user01',
              type: 1,
              name: '张三'
            }]
          },
          {
            id: 'dept02',
            type: 2,
            name: '人事部门',
            children: []
          }
        ]

        state.roleList = null

        const response = await fetch(new URL('../../../src/assets/leave.json', import.meta.url).href)
        const json = await response.json()

        state.formTemplates = [
          {
            title: '请假表单2',
            img: new URL('../../../src/assets/leave.jpg', import.meta.url).href,
            json
          }]

        const resData = {
          'flowPermission': [],
          'nodeConfig': {
            'nodeName': '发起人',
            'type': 0,
            'conditionList': [],
            'nodeUserList': [],
            'priorityLevel': '',
            'settype': '',
            'selectMode': '',
            'selectRange': '',
            'directorLevel': '',
            'superiorApproval': '',
            'examineMode': '',
            'noHanderAction': '',
            'examineEndDirectorLevel': '',
            'ccSelfSelectFlag': '',
            'childNode': {
              'nodeName': '路由',
              'type': 4,
              'childNode': {
                'nodeName': '抄送人',
                'type': 2,
                'ccSelfSelectFlag': 1,
                'childNode': null,
                'nodeUserList': [],
                'error': false
              },
              'conditionNodes': [
                {
                  'nodeName': '条件1',
                  'error': false,
                  'type': 3,
                  'priorityLevel': 1,
                  'conditionList': [
                    {
                      'id': 'input69324',
                      'index': 1,
                      'type': 'number',
                      'name': 'leaveDays',
                      'label': '请假时长',
                      'value': 3,
                      'optType': '<'
                    }
                  ],
                  'nodeUserList': [],
                  'childNode': {
                    'nodeName': '审核人',
                    'error': false,
                    'type': 1,
                    'settype': 4,
                    'selectMode': 1,
                    'selectRange': 1,
                    'directorLevel': 1,
                    'examineMode': 1,
                    'noHanderAction': 1,
                    'superiorApproval': true,
                    'examineEndDirectorLevel': 1,
                    'childNode': null,
                    'nodeUserList': []
                  }
                },
                {
                  'nodeName': '条件2',
                  'type': 3,
                  'priorityLevel': 2,
                  'conditionList': [],
                  'nodeUserList': [],
                  'childNode': {
                    'nodeName': '审核人',
                    'error': false,
                    'type': 1,
                    'settype': 1,
                    'selectMode': 1,
                    'selectRange': 1,
                    'directorLevel': 1,
                    'examineMode': 1,
                    'noHanderAction': 1,
                    'superiorApproval': true,
                    'examineEndDirectorLevel': 1,
                    'childNode': null,
                    'nodeUserList': [
                      {
                        'id': 'user01',
                        'type': 1,
                        'name': '张三'
                      }
                    ]
                  },
                  'error': false
                }
              ]
            },
            'conditionNodes': []
          },
          'tableId': '202200001',
          'workFlowDef': {
            'flowName': '请假',
            'flowImg': '2',
            'flowGroup': '1',
            'flowRemark': ''
          },
          'formMaking': {
            'widgetList': [
              {
                'type': 'select',
                'name': '选择器',
                'icon': 'select-field',
                'options': {
                  'name': 'Type',
                  'label': '请假类型',
                  'width': 100,
                  'defaultValue': null,
                  'optionItems': [
                    {
                      'label': '年假',
                      'value': '1'
                    },
                    {
                      'label': '事假',
                      'value': '2'
                    },
                    {
                      'label': '病假',
                      'value': '3'
                    },
                    {
                      'label': '调休假',
                      'value': 4
                    },
                    {
                      'label': '婚假',
                      'value': 5
                    },
                    {
                      'label': '丧假',
                      'value': 6
                    },
                    {
                      'label': '产假',
                      'value': 7
                    },
                    {
                      'label': '陪产假',
                      'value': 8
                    },
                    {
                      'label': '产检假',
                      'value': 9
                    },
                    {
                      'label': '哺乳假',
                      'value': 10
                    },
                    {
                      'label': '陪考假',
                      'value': 11
                    },
                    {
                      'label': '其他',
                      'value': 12
                    }
                  ],
                  'source': 'static',
                  'action': '/api/basic/approval/leave-types',
                  'placeholder': '请选择',
                  'required': true,
                  'requiredMessage': '请选择请假类型'
                },
                'events': {
                  'onChange': '',
                  'onFocus': '',
                  'onBlur': ''
                },
                'id': 'select73665'
              },
              {
                'type': 'date',
                'name': '日期选择',
                'icon': 'date-field',
                'options': {
                  'name': 'BTime',
                  'label': '开始时间',
                  'width': 100,
                  'defaultValue': null,
                  'type': 'datetime',
                  'format': '',
                  'placeholder': '请选择',
                  'required': true,
                  'requiredMessage': '请选择开始时间'
                },
                'events': {
                  'onChange': '',
                  'onFocus': '',
                  'onBlur': '',
                  'onValidate': "const { BTime, ETime } = formData;\r\nif(BTime && ETime) {\r\n  const startTime = new Date(BTime); // 开始时间\r\n  const endTime = new Date(ETime); // 结束时间\r\n  if(startTime >= endTime) {\r\n    callback('开始时间不能大于结束时间')\r\n  }\r\n}\r\ncallback()"
                },
                'id': 'date75827'
              },
              {
                'type': 'date',
                'name': '日期选择',
                'icon': 'date-field',
                'options': {
                  'name': 'ETime',
                  'label': '结束时间',
                  'width': 100,
                  'defaultValue': null,
                  'type': 'datetime',
                  'format': '',
                  'placeholder': '请选择',
                  'required': true,
                  'requiredMessage': '请选择结束时间'
                },
                'events': {
                  'onChange': "// 自动计算请假时长\r\nconst { BTime, ETime, leaveDays } = formData;\r\nif(BTime && ETime) {\r\n  const startTime = new Date(BTime); // 开始时间\r\n  const endTime = new Date(ETime); // 结束时间\r\n  const diffTime = endTime - startTime;  // 毫秒数\r\n  const diffHours = Math.ceil((endTime - startTime) / 1000 / 60 / 60) // 小时\r\n  const diffDays = Math.ceil((endTime - startTime) / 1000 / 60 / 60 / 24) //天数\r\n  formData['leaveDays'] = diffDays;\r\n}",
                  'onFocus': '',
                  'onBlur': '',
                  'onValidate': ''
                },
                'id': 'date102257'
              },
              {
                'type': 'input',
                'name': '输入框',
                'icon': 'input-field',
                'options': {
                  'name': 'leaveDays',
                  'label': '请假时长',
                  'width': 100,
                  'defaultValue': '0',
                  'type': 'number',
                  'min': 0,
                  'max': 30,
                  'maxlength': '',
                  'placeholder': '',
                  'append': '天',
                  'required': true,
                  'requiredMessage': '请输入请假时长'
                },
                'events': {
                  'onChange': '',
                  'onFocus': '',
                  'onBlur': '',
                  'onValidate': ''
                },
                'id': 'input69324'
              },
              {
                'type': 'textarea',
                'name': '多行输入',
                'icon': 'textarea-field',
                'options': {
                  'name': 'remark',
                  'label': '请假事由',
                  'width': 100,
                  'defaultValue': '',
                  'maxlength': '100',
                  'rows': 3,
                  'autosize': false,
                  'placeholder': '请输入',
                  'required': false,
                  'requiredMessage': '不能为空！'
                },
                'events': {
                  'onChange': '',
                  'onFocus': '',
                  'onBlur': ''
                },
                'id': 'textarea75241'
              }
            ],
            'formConfig': {
              'size': 'default',
              'labelWidth': 80,
              'labelPosition': 'right',
              'inputPosition': 'right',
              'flex': true,
              'paddingLeft': 8,
              'paddingRight': 8,
              'useTemplate': 1,
              'editable': 0
            }
          },
          'advanced': {
            'flowAdvice': true,
            'allowRevoke': false,
            'flowApproval': 0
          }
        }

        /** 数据关联 - 勿删 */
        const { tableId, workFlowDef, formMaking, flowPermission, nodeConfig } = resData
        _.merge(state, { workFlowDef, formMaking })
        _.merge(processConfig, { tableId, flowPermission, nodeConfig })

        loading.close()
      }, 3000)
    })

    /** 后退按钮事件 */
    const toReturn = () => {
      console.log('toReturn :>> ')
    }

    /** 发布 */
    const saveSet = () => {
      workflowRef.value.setChange()
    }

    /** 保存事件 */
    const onChange = (config) => {
      basicRef.value.validate().then(workFlowDef => {
        if (state.formMaking.widgetList.length === 0) {
          activeStep.value = 1
          notification.warning('表单不能为空.')
          return false
        }
        config.workFlowDef = workFlowDef
        config.formMaking = state.formMaking
        config.advanced = state.advanced
        console.log('config :>> ', config)
        console.log('configJson :>> ', JSON.stringify(config))
      }).catch(error => {
        activeStep.value = 0
        console.log('error :>> ', error)
      })
    }

    return {
      ...toRefs(state),
      processConfig,
      activeStep,
      basicRef,
      workflowRef,
      dialogVisible,
      formMakingOptions,
      hideFields,
      usedConditionIds,
      toReturn,
      saveSet,
      onChange
    }
  }
}
</script>

<style lang="scss" scoped>

.rovalflow-container {
  height: 100%;
  position: relative;

  .header {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 997;
    width: 100%;
    height: 60px;
    font-size: 14px;
    color: #fff;
    background: var(--ep-color-primary);
    display: flex;
    align-items: center;
  }
  .header-left {
    flex: 1;
    display: flex;
    align-items: center;
  }
  .header-center {
    width: 600px;
    text-align: center;
  }
  .header-right {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: flex-end;
    text-align: right;
  }

  .nav-back {
    display: inline-block;
    width: 60px;
    height: 60px;
    font-size: 22px;
    border-right: 1px solid var(--ep-color-primary-dark-2);
    text-align: center;
    cursor: pointer;

    &:hover {
      background: var(--ep-color-primary-light-3);
    }
    &:active {
      background: var(--ep-color-primary-dark-2);
    }
    &>.m-icon {
      height: 60px;
    }
  }

  .nav-title {
    width: 0;
    flex: 1;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    padding: 0 15px;
  }

  .nav-container {
    display: inline-block;
    position: relative;

    .ghost-bar {
      position: absolute;
      width: 150px;
      height: 100%;
      left: 0;
      background: var(--ep-color-primary-dark-2);
      transition: all .3s cubic-bezier(.645, .045, .355, 1);
    }

    .ghost-bar:after {
      content: "";
      position: absolute;
      bottom: 0;
      left: 50%;
      margin-left: -5px;
      width: 0;
      height: 0;
      border-style: solid;
      border-width: 0 5px 6px;
      border-color: transparent transparent var(--ep-color-info-light-9);
    }
    .nav-item {
      position: relative;
      cursor: pointer;
      display: inline-block;
      line-height: 60px;
      width: 150px;
      text-align: center;
      white-space: nowrap;
    }

    .nav-item .order-num {
      display: inline-block;
      width: 20px;
      height: 20px;
      line-height: 20px;
      border: 1px solid #fff;
      border-radius: 50%;
      margin-right: 6px;
      transition: all .3s cubic-bezier(.645, .045, .355, 1);
    }

    .nav-item.active .order-num {
      color: var(--ep-color-primary-dark-2);
      background: #fff;
    }
  }

  .main {
    position: fixed;
    top: 60px;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 1;
    overflow-x: hidden;
    overflow-y: auto;
    padding: 0;
    background-color: var(--ep-color-info-light-9);

    .setting-container {
      width: 600px;
      margin: auto;
      background: #fff;
      padding: 16px;
      overflow: auto;
      position: absolute;
      bottom: 20px;
      left: 0;
      right: 0;
      top: 10px;
    }
    .content-container {
      position: relative;
      height: 100%;
    }
  }
}

</style>
